package com.pt25.base.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * tokenUtil主要用来生成token和解析token
 */
public class TokenUtil {

    /**
     * calendarInterval 过期时间: 10天
     */
    public static final int calendarField = Calendar.DATE;
    public static final int calendarInterval = 10;


    /**
     * 加密token
     *
     * @param obj    需要加密的对象
     * @param secret 秘钥
     */
    public static String encryptToken(Object obj, String secret) {
        return encryptTokenPublic(obj, secret, calendarField, calendarInterval);
    }

    /**
     * 加密token(自己设个过期规则和过期时间)
     *
     * @param obj    需要加密的对象
     * @param secret 秘钥
     */
    public static String encryptToken(Object obj, String secret, Integer calendarField, Integer calendarInterval) {
        return encryptTokenPublic(obj, secret, calendarField, calendarInterval);
    }

    private static String encryptTokenPublic(Object obj, String secret, Integer calendarField, Integer calendarInterval) {
        try {
            Date iatDate = new Date();
            Calendar nowTime = Calendar.getInstance();
            nowTime.add(calendarField, calendarInterval);
            Date expiresDate = nowTime.getTime();
            Map<String, Object> map = new HashMap<>();
            map.put("alg", "HS256");
            map.put("typ", "JWT");
            // header
            // sign time
            // expire time
            // signature
            return JWT.create().withHeader(map) // header
                    .withClaim("secret_token", JsonUtil.toJson(obj))
                    .withIssuedAt(iatDate) // sign time
                    .withExpiresAt(expiresDate) // expire time
                    .sign(Algorithm.HMAC256(secret));
        } catch (Exception e) {
            throw new RuntimeException("获取token异常:" + e.getMessage());
        }
    }


    /**
     * 解密token
     *
     * @param token token
     * @param c     解密后对象的class
     * @param <T>   加密对象类型
     */
    public static <T> T decryptToken(String token, String secret, Class<T> c) {
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret)).build();
            token = token.replace("Bearer", "").trim();
            DecodedJWT jwt = verifier.verify(token);
            Map<String, Claim> claims = jwt.getClaims();
            Claim claim = claims.get("secret_token");
            return JsonUtil.toBean(claim.asString(), c);
        } catch (Exception e) {
            throw new RuntimeException("解析token异常:" + e.getMessage());
        }
    }

}
